/*
 * Created on Dec 30, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package org.scohen.juploadr.app;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;
import org.scohen.juploadr.Messages;
import org.scohen.juploadr.app.carbon.CarbonMenuEventHandler;
import org.scohen.juploadr.app.state.RestoreStateTask;
import org.scohen.juploadr.app.state.SaveStateTask;
import org.scohen.juploadr.prefs.Configuration;
import org.scohen.juploadr.prefs.ConfigurationDialog;
import org.scohen.juploadr.ui.MessageUtils;
import org.scohen.juploadr.ui.ProgressDialog;
import org.scohen.juploadr.ui.ReusableUIFactory;
import org.scohen.juploadr.ui.thumbnail.Thumbnail;
import org.scohen.juploadr.upload.UploadManager;
import org.scohen.juploadr.uploadapi.Account;
import org.scohen.juploadr.uploadapi.CommunicationException;
import org.scohen.juploadr.uploadapi.ImageUploadApi;
import org.scohen.juploadr.uploadapi.PluginClassLoader;
import org.scohen.juploadr.uploadapi.ProtocolException;
import org.scohen.juploadr.util.JUploadrBrowserLauncher;
import org.scohen.juploadr.util.LogUtil;

/**
 * @author steve
 * 
 * TODO To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Style - Code Templates
 */
public class JUploadr {
    public static Shell window;
    private TrayItem myItem;
    private Map<String, ImageAttributes> imageAttributes;
    private Image logo;
    private Image tinyLogo;
    public Composite images;
    public Composite buttonRow;
    private ScrolledComposite imageContainer;
    private ProgressBar progress;
    final TextTransfer textTransfer = TextTransfer.getInstance();
    final FileTransfer fileTransfer = FileTransfer.getInstance();
    private Button btnSubmit;
    private boolean shouldDie = false;
    private ReusableUIFactory reusableUIFactory;
    private JUploadrEventDirector director;
    private Button loginButton;
    private Menu sites;
    private MenuItem implementations;
    private boolean donateLinkClicked = false;

    public JUploadr() {
        director = new JUploadrEventDirector(this);
        reusableUIFactory = ReusableUIFactory.getInstance();
        logo = reusableUIFactory.getLogoImage();
        tinyLogo = reusableUIFactory.getTinyLogoImage();
        imageAttributes = new LinkedHashMap<String, ImageAttributes>();

        initUI();
    }

    private void initUI() {
        window = new Shell(reusableUIFactory.getDisplay());

        buildMenu(window);
        imageContainer = new ScrolledComposite(window, SWT.V_SCROLL | SWT.BORDER);
        images = new Composite(imageContainer, SWT.NONE);
        images.addMouseListener(director.mouseListener);
        imageContainer.addMouseListener(director.mouseListener);
        imageContainer.setContent(images);
        imageContainer.setBackground(reusableUIFactory.getWhiteColor());
        imageContainer.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent arg0) {
                JUploadr.this.paintControl(arg0);
            }
        });

        RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
        rowLayout.spacing = 5;
        images.setLayout(rowLayout);
        images.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent event) {
                JUploadr.this.paintControl(event);
            }
        });

        images.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseUp(MouseEvent event) {
                JUploadr.this.mouseClicked(event);
            }

        });
        addDropTarget(imageContainer);
        addDropTarget(images);

        imageContainer.addKeyListener(director.keyListener);
        images.addKeyListener(director.keyListener);
        window.addKeyListener(director.keyListener);
        images.setBackground(reusableUIFactory.getWhiteColor());

        createButtonRow();

        FormLayout windowLayout = new FormLayout();
        windowLayout.spacing = 5;
        window.setLayout(windowLayout);

        FormData imgData = new FormData();
        imgData.top = new FormAttachment(0, 1);
        imgData.right = new FormAttachment(100, 1);
        imgData.bottom = new FormAttachment(100, (0 - buttonRow.computeSize(SWT.DEFAULT, SWT.DEFAULT).y));

        imgData.left = new FormAttachment(0, 1);
        imageContainer.setLayoutData(imgData);

        FormData buttonData = new FormData();
        buttonData.top = new FormAttachment(imageContainer, 0);
        buttonData.bottom = new FormAttachment(100, 0);
        buttonData.right = new FormAttachment(100, 0);
        buttonData.left = new FormAttachment(0, 0);
        buttonRow.setLayoutData(buttonData);
        // don't set the logo if it's mac OS, since our app bundle has a
        // better logo
        if (!Configuration.isMac()) {
            window.setImage(tinyLogo);
            myItem = createTray(reusableUIFactory.getDisplay(),
                    Messages.getString("juploadr.ui.application.name"), //$NON-NLS-1$
                    tinyLogo);
            addDisposable(myItem);
        }

        window.setSize(4 * Thumbnail.TOTAL_WIDTH + 50, 5 * Thumbnail.TOTAL_HEIGHT + 50);

        window.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent event) {
                JUploadr.this.paintControl(event);
            }
        });

        window.addControlListener(new ControlAdapter() {
            public void controlResized(ControlEvent e) {
                Rectangle bounds = ((Control) e.widget).getBounds();
                JUploadr.this.imageContainer.getVerticalBar().setPageIncrement(bounds.height);
            }
        });
        window.addKeyListener(director.keyListener);

        window.setText(Messages.getString("juploadr.ui.application.name")); //$NON-NLS-1$

        imageContainer.getVerticalBar().setPageIncrement(imageContainer.getBounds().height);

    }

    private void addDisposable(Object blah) {
    }

    /**
     * 
     */
    private void createButtonRow() {
        int iconHeight = ImageUploadApi.getInstance().getIcon().getImageData().y;

        buttonRow = new Composite(window, SWT.NONE);
        GridLayout layout = new GridLayout(3, true);
        layout.marginBottom = 5;
        buttonRow.setLayout(layout);

        progress = new ProgressBar(buttonRow, SWT.HORIZONTAL | SWT.SMOOTH);
        progress.setForeground(reusableUIFactory.getProgressBarColor());

        progress.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false));

        btnSubmit = new Button(buttonRow, SWT.PUSH);
        btnSubmit.setText(Messages.getString("juploadr.ui.button.upload.text.upload")); //$NON-NLS-1$);
        btnSubmit.addSelectionListener(new UploadManager(imageAttributes, director));
        btnSubmit.setEnabled(false);
        btnSubmit.setSize(btnSubmit.computeSize(SWT.DEFAULT, iconHeight));

        loginButton = new Button(buttonRow, SWT.PUSH);
        final ImageUploadApi api = ImageUploadApi.getInstance();
        loginButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                JUploadrBrowserLauncher.openURL(ImageUploadApi.getInstance().getCurrentAccount().getPhotoURL()
                        .toString());
            }
        });
        loginButton.setImage(api.getIcon());
        loginButton.setText(api.getCurrentAccount().getUsername() + "@" + api.getSiteName());

        btnSubmit.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, false));
        loginButton.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false));
        loginButton.setEnabled(ImageUploadApi.getInstance().isCurrentAccountAuthenticated());

        addDisposable(btnSubmit);
        addDisposable(progress);
        addDisposable(buttonRow);
        buttonRow.pack();
    }

    private void addDropTarget(Composite composite) {
        DropTarget target = new DropTarget(composite, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);

        Transfer[] types = new Transfer[] { fileTransfer, textTransfer };
        target.setTransfer(types);
        target.addDropListener(director.dropTargetListener);
        addDisposable(target);
    }

    /**
     * 
     */
    public void startup() {
        if (ImageUploadApi.getInstance().isCurrentAccountAuthenticated()) {
            Thread t = new Thread() {
                public void run() {
                    ImageUploadApi.getInstance();
                }
            };
            t.start();
        }

        window.open();
        RestoreStateTask restore = new RestoreStateTask(this);
        ProgressDialog dialog = new ProgressDialog(JUploadr.window, restore);
        dialog.execute();
        while (!window.isDisposed()) {
            if (!reusableUIFactory.getDisplay().readAndDispatch()) {
                reusableUIFactory.getDisplay().sleep();
            }
        }
    }

    private Menu buildMenu(Shell parent) {
        Menu bar = new Menu(parent, SWT.BAR);
        Menu submenu;
        MenuItem child;

        parent.setMenuBar(bar);

        // The file menu on macs only has the exit command in it, which is in
        // the
        // application's menu and is redundant.
        if (!Configuration.isMac()) {
            MenuItem file = new MenuItem(bar, SWT.CASCADE);
            file.setText(Messages.getString("juploadr.ui.menu.file")); //$NON-NLS-1$
            file.setAccelerator(SWT.CTRL + 'F');
            submenu = new Menu(parent, SWT.DROP_DOWN);

            child = new MenuItem(submenu, SWT.CASCADE);
            child.setText(Messages.getString("juploadr.ui.menu.add.photo"));
            child.setAccelerator(SWT.ALT + 'A');
            child.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    String[] extensions = ImageUploadApi.getInstance().getAbilities().getUploadAbilities()
                            .getUploadFileTypesAsGlobs();
                    final FileDialog dialog = new FileDialog(JUploadr.window, SWT.MULTI);
                    dialog.setFilterExtensions(extensions);
                    dialog.setFilterPath(System.getProperty("user.home")); //$NON-NLS-1$
                    dialog.open();
                    final String[] selected = dialog.getFileNames();
                    if (selected != null && selected.length > 0) {
                        for (int i = 0; i < selected.length; i++) {
                            JUploadr.this.addButton(dialog.getFilterPath() + File.separator + selected[i]);
                        }
                    }
                }
            });
            child = new MenuItem(submenu, SWT.PUSH);
            child.setText("Save Changes");
            child.setAccelerator(SWT.ALT + 'S');
            child.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent event) {
                    JUploadr.this.saveState();
                }

            });
            child = new MenuItem(submenu, SWT.PUSH);
            child.setText(Messages.getString("juploadr.ui.menu.file.exit")); //$NON-NLS-1$
            child.setAccelerator('x');
            child.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent arg0) {
                    JUploadr.this.quit();
                }
            });
            addDisposable(child);
            addDisposable(submenu);
            file.setMenu(submenu);
        }
        MenuItem view = new MenuItem(bar, SWT.CASCADE);
        view.setText(Messages.getString("juploadr.ui.menu.edit")); //$NON-NLS-1$
        view.setAccelerator(SWT.ALT + 'E');
        submenu = new Menu(parent, SWT.DROP_DOWN);

        child = new MenuItem(submenu, SWT.CHECK);
        child.setText(Messages.getString("juploadr.ui.photo.decorations.enable")); //$NON-NLS-1$
        child.setSelection(Configuration.getInstance().getUseImageLayovers());
        child.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                MenuItem item = (MenuItem) event.widget;
                Configuration.getInstance().setUseImageLayovers(item.getSelection());
                JUploadr.this.refresh();
            }
        });
        addDisposable(child);

        addLanguagesMenu(submenu);
        addAccountsMenu(submenu);

        if (!Configuration.isMac()) {
            child = new MenuItem(submenu, SWT.PUSH);
            child.setText(Messages.getString("juploadr.ui.menu.edit.preferences")); //$NON-NLS-1$
            child.setAccelerator('P');
            child.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent arg0) {
                    ConfigurationDialog setup = new ConfigurationDialog(window);
                    setup.setText(Messages.getString("juploadr.ui.dialog.preferences")); //$NON-NLS-1$
                    setup.open();
                }
            });
            addDisposable(child);
        } else {
            CarbonMenuEventHandler handler = new CarbonMenuEventHandler(this);
            handler.hookApplicationMenu(ReusableUIFactory.getInstance().getDisplay(), Messages.getString(
                    "juploadr.ui.menu.help.about").substring(1)
                    + " jUploadr"); // $Non-NLS-1$
        }
        addDisposable(submenu);
        addDisposable(view);
        view.setMenu(submenu);
        if (!Configuration.isMac()) {
            MenuItem help = new MenuItem(bar, SWT.CASCADE);
            help.setText(Messages.getString("juploadr.ui.menu.help")); //$NON-NLS-1$
            help.setAccelerator(SWT.HELP);
            addDisposable(help);
            submenu = new Menu(parent, SWT.DROP_DOWN);
            child = new MenuItem(submenu, SWT.PUSH);
            child.setText(Messages.getString("juploadr.ui.menu.help.about")); //$NON-NLS-1$
            child.setAccelerator('A');

            child.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent event) {
                    new AboutDialog();

                }
            });
            addDisposable(child);
            help.setMenu(submenu);
        }
        addDisposable(bar);
        return bar;
    }

    /**
     * 
     */
    private void saveState() {
        new ProgressDialog(reusableUIFactory.getDisplay().getActiveShell(), new SaveStateTask(JUploadr.this))
                .execute();
    }

    void addLanguagesMenu(Menu submenu) {
        MenuItem languages = new MenuItem(submenu, SWT.CASCADE);
        Menu languageOptions = new Menu(languages);
        languages.setMenu(languageOptions);

        languages.setText(Messages.getString("juploadr.ui.menu.language")); //$NON-NLS-1$
        final Configuration config = Configuration.getInstance();
        Locale[] locales = config.getValidLocales();
        for (int i = 0; i < locales.length; i++) {
            Locale locale = locales[i];

            MenuItem language = new MenuItem(languageOptions, SWT.CHECK);

            language.setText(Character.toUpperCase(locale.getDisplayLanguage(locale).charAt(0))
                    + locale.getDisplayLanguage(locale).substring(1));
            language.setData(locale);
            language.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent event) {
                    MenuItem lang = (MenuItem) event.widget;
                    Menu parent = lang.getParent();
                    MenuItem[] kids = parent.getItems();
                    for (int i = 0; i < kids.length; i++) {
                        MenuItem child = kids[i];
                        if (child.getSelection() && child != lang) {
                            child.setSelection(false);
                        }
                    }
                    config.setLocale((Locale) lang.getData());
                    JUploadr.this.restart();
                }
            });
            if (config.getLocale().getLanguage().equals(locale.getLanguage())) {
                language.setSelection(true);
            }
            addDisposable(language);
        }
        addDisposable(languages);
    }

    void addAccountsMenu(Menu submenu) {

        implementations = new MenuItem(submenu, SWT.CASCADE);
        implementations.setText(Messages.getString("juploadr.ui.menu.uploadto")); //$NON-NLS-1$
        sites = new Menu(implementations);
        implementations.setMenu(sites);
        addAccountMenuData(implementations);

    }

    /**
     * @param imps
     * @param implementations
     */
    private void addAccountMenuData(MenuItem implementations) {
        ImageUploadApi[] imps = ImageUploadApi.getRegisteredImplemtations();
        List allAccounts = ImageUploadApi.allAccountsForAllApis();
        Iterator iter = allAccounts.iterator();

        while (iter.hasNext()) {
            Account a = (Account) iter.next();
            MenuItem accountItem = new MenuItem(sites, SWT.CHECK);
            accountItem.setText(a.getName() + "@" + a.getApi().getSiteName());
            accountItem.setData(a);
            accountItem.setSelection(a.equals(ImageUploadApi.getInstance().getCurrentAccount()));
            accountItem.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent event) {
                    Account selected = (Account) event.widget.getData();
                    if (!selected.getApi().equals(ImageUploadApi.getInstance())) {
                        ImageUploadApi.changeImplementation(selected.getApi().getClass().getName(), JUploadr.this);
                    }
                    ImageUploadApi.getInstance().setCurrentAccount(selected);
                    JUploadr.this.loginButton.setImage(ImageUploadApi.getInstance().getIcon());
                    JUploadr.this.loginButton.setText(ImageUploadApi.getInstance().getCurrentAccount()
                            .getUsername()
                            + "@" + ImageUploadApi.getInstance().getSiteName());
                    JUploadr.this.loginButton.setSize(JUploadr.this.loginButton.computeSize(SWT.DEFAULT,
                            SWT.DEFAULT));
                    buttonRow.layout();
                    JUploadr.this.refresh();
                    MenuItem[] kids = ((MenuItem) event.widget).getParent().getItems();
                    for (int i = 0; i < kids.length; i++) {
                        kids[i].setSelection(kids[i] == event.widget);
                    }
                }
            });
            addDisposable(accountItem);
        }

        if (allAccounts.size() > 0) {
            MenuItem sep = new MenuItem(sites, SWT.SEPARATOR);
            addDisposable(sep);
        }

        for (int i = 0; i < imps.length; i++) {
            ImageUploadApi imp = imps[i];
            MenuItem item = new MenuItem(sites, SWT.PUSH);
            item.setText(Messages.getString("juploadr.ui.menu.newaccount", imp.getSiteName())); //$NON-NLS-1$
            item.setImage(imp.getIcon());
            item.setData(imp);
            addDisposable(item);
            final MenuItem localImplementations = implementations;
            item.addSelectionListener(new SelectionAdapter() {
                public void widgetSelected(SelectionEvent event) {
                    ImageUploadApi api = (ImageUploadApi) event.widget.getData();
                    ImageUploadApi.changeImplementation(api.getClass().getName(), JUploadr.this);

                    try {
                        api.authenticate(api.newAccount("--"));
                        api.setCurrentAccount(api.getCurrentAccount());
                        /*
                         * add the new account to the implementations menu
                         */
                        MenuItem[] kids = sites.getItems();
                        for (int j = 0; j < kids.length; j++) {
                            kids[j].dispose();
                        }
                        JUploadr.this.addAccountMenuData(localImplementations);
                    } catch (ProtocolException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (CommunicationException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });

        }
    }

    public void addButton(String imagePath) {
        addButton(imagePath, 0);
    }

    public void addButton(String imagePath, int rotation) {
        if (imageAttributes.get(imagePath) == null) {
            ImageAttributes attributes = new ImageAttributes(this, images, imagePath, rotation);
            attributes.getButton().addMouseListener(director.mouseListener);
            attributes.getButton().addKeyListener(director.keyListener);
            images.setSize(images.computeSize(SWT.DEFAULT, SWT.DEFAULT));
            imageContainer.setMinSize(images.computeSize(SWT.DEFAULT, SWT.DEFAULT));

            images.layout();
            attributes.setRank(imageAttributes.size());
            imageAttributes.put(attributes.getKey(), attributes);
        } else {
            // select the photo
            imageAttributes.get(imagePath).setSelected(true);
            refresh();
            MessageUtils.showErrorMessage(Messages.getString("juploadr.ui.error.image.added.already")); //$NON-NLS-1$
        }
    }

    private TrayItem createTray(Display display, String tooltip, final Image image) {
        TrayItem item = null;
        final Tray tray = display.getSystemTray();
        if (tray != null) {
            item = new TrayItem(tray, SWT.NONE);
            item.setImage(image);
            if (tooltip != null) {
                item.setToolTipText(tooltip);
            }
            item.addListener(SWT.Selection, director.listener);
            item.addListener(SWT.DefaultSelection, director.listener);
            item.addListener(SWT.MenuDetect, director.listener);
        }
        return item;
    }

    public void refresh() {
        Iterator iter = imageAttributes.keySet().iterator();

        while (iter.hasNext()) {
            String key = (String) iter.next();
            ImageAttributes att = imageAttributes.get(key);
            if (att.getState() == UploadImage.STATE_REMOVED) {
                iter.remove();
            } else {
                // this is for OS X, since it doesn't redraw the attributes if
                // their
                // state has changed.
                att.getButton().redraw();
            }

        }
        buttonRow.layout();
        images.redraw();
        window.redraw();
    }

    ProgressBar getProgressBar() {
        return progress;
    }

    Button getUploadButton() {
        return btnSubmit;
    }

    FileTransfer getFileTransfer() {
        return fileTransfer;
    }

    public void mouseClicked(MouseEvent e) {
        if (!donateLinkClicked) {
            donateLinkClicked = true;
            window.redraw();
            JUploadrBrowserLauncher.openURL("https://sourceforge.net/donate/index.php?group_id=127771");
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
     */
    public void paintControl(PaintEvent event) {
        GC gfx;
        Point size;

        gfx = new GC(images);

        if (imageAttributes.isEmpty()) {
            List<String> lines = new LinkedList<String>();
            lines.add(Messages.getString("juploadr.ui.instructions")); //$NON-NLS-1$
            if (!donateLinkClicked) {
                lines.add(Messages.getString("juploadr.ui.or")); //$NON-NLS-1$
                lines.add(Messages.getString("juploadr.ui.clicktodonate")); //$NON-NLS-1$
            }
            size = window.getSize();
            int width = size.x;

            gfx.drawImage(logo, width / 2 - logo.getBounds().width / 2, 5);
            int height = drawCenteredText(lines, gfx, logo.getBounds().height + 15, width);
            images.setSize(width, height);

            btnSubmit.setEnabled(false);
        } else {

            size = imageContainer.getSize();
            btnSubmit.setEnabled(true);
            images.setSize(images.computeSize(size.x, SWT.DEFAULT));
        }

        Account current = ImageUploadApi.getInstance().getCurrentAccount();
        if (loginButton.getText().indexOf(current.getUsername()) < 0) {
            loginButton.setText(current.getUsername() + "@" + ImageUploadApi.getInstance().getSiteName());
            loginButton.setEnabled(ImageUploadApi.getInstance().isCurrentAccountAuthenticated());
            loginButton.setImage(ImageUploadApi.getInstance().getIcon());
            loginButton.setSize(loginButton.computeSize(SWT.DEFAULT, SWT.DEFAULT));

            buttonRow.layout();
        }
        gfx.dispose();

    }

    private int drawCenteredText(List<String> lines, GC gfx, int initialY, int width) {

        for (String line : lines) {
            Point textSize = gfx.textExtent(line);
            gfx.drawString(line, width / 2 - (textSize.x) / 2, initialY);
            initialY += textSize.y;
        }
        return initialY;
    }

    public void removeUploadedPhotos() {
        Iterator<ImageAttributes> values = imageAttributes.values().iterator();
        while (values.hasNext()) {
            ImageAttributes element = values.next();
            if (element.getState() == UploadImage.STATE_UPLOADED
                    || element.getState() == UploadImage.STATE_REMOVED) {
                values.remove();
                element.removeFromWindow();
                element.dispose();
            }

        }
        refresh();
    }

    /**
     * @return Returns the imageAttributes.
     */
    public Map<String, ImageAttributes> getImageAttributes() {
        return imageAttributes;
    }

    public void quit() {
        SaveStateTask saveState = new SaveStateTask(this);
        ProgressDialog dialog = new ProgressDialog(JUploadr.window, saveState);
        dialog.execute();
        shouldDie = true;
        window.close();
    }

    public void restart() {
        shouldDie = true;
        if (!Configuration.isMac()) {
            myItem.dispose();
        }
        window.close();
        window.dispose();
        initUI();
        imageContainer.redraw();
        startup();
    }

    public static void main(String[] args) throws Throwable {
        LogUtil.init();
        Thread.currentThread().setContextClassLoader(PluginClassLoader.getInstance());
        List argList = Arrays.asList(args);

        if (System.getProperty("java.vm.name").indexOf("gcj") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
            System.out.println(Messages.getString("juploadr.ui.gcj.incompatible")); //$NON-NLS-1$
            System.exit(0);
        }
        if (argList.contains("--help")) { //$NON-NLS-1$
            System.out.println("\n\n./jUploadr [-proxy] [--reset-preferences]\n"); //$NON-NLS-1$
            System.exit(0);
        }
        if (argList.contains("--reset-preferences")) { //$NON-NLS-1$
            Configuration.getInstance().resetAllPrefs();
        }
        if (args != null && args.length > 0 && "-proxy".equals(args[0])) { //$NON-NLS-1$
            System.setProperty("proxy", "true"); //$NON-NLS-1$ //$NON-NLS-2$
            Configuration.getInstance().setProxyEnabled(true);
        }
        JUploadr j = new JUploadr();
        try {
            j.startup();
        } catch (Throwable t) {
            LogFactory.getLog(JUploadr.class).fatal("juploadr died", t);
            j.saveState();
            throw t;
        }
    }

}